<template>
  <div class="apply page">
    <Title v-if="status !== statusMap.UPLOAD" />
    <div class="form animate__animated animate__zoomIn" v-if="status === statusMap.SUBMIT">
      <div class="form-item">
        <div class="icon"><i class="bg-full"></i></div>
        <div class="label">分公司</div>
        <div class="control">
          <select v-model="formData.company">
            <option value="">请选择分公司</option>
            <option v-for="(item, index) in companyList" :key="index" :value="item">
              {{ item }}
            </option>
          </select>
        </div>
      </div>
      <div class="form-item">
        <div class="icon"><i class="bg-full"></i></div>
        <div class="label">姓名</div>
        <div class="control">
          <input type="text" placeholder="输入姓名" v-model="formData.name" />
        </div>
      </div>
      <div class="form-item">
        <div class="icon"><i class="bg-full"></i></div>
        <div class="label">工号</div>
        <div class="control">
          <input type="text" placeholder="内勤输入P13，外勤输入工号" v-model="formData.number" />
        </div>
      </div>
      <div class="form-item">
        <div class="icon"><i class="bg-full"></i></div>
        <div class="label">比武组别</div>
        <div class="control">
          <select v-model="formData.group">
            <option value="">请选择比武组别</option>
            <option v-for="(item, index) in groupList" :key="index" :value="item">
              {{ item }}
            </option>
          </select>
        </div>
      </div>
      <div class="form-item">
        <div class="icon"><i class="bg-full"></i></div>
        <div class="label">比武类别</div>
        <div class="control">
          <select v-model="formData.category">
            <option value="">请选择比武类别</option>
            <option v-for="(item, index) in categoryList" :key="index" :value="item">
              {{ item }}
            </option>
          </select>
        </div>
      </div>
      <div class="form-item">
        <div class="icon"><i class="bg-full"></i></div>
        <div class="label">参赛作品名称</div>
        <div class="control">
          <input type="text" v-model="formData.works" />
        </div>
      </div>
      <div class="form-item submit bg-full" @click="handleSubmit"></div>
    </div>
    <div class="result" v-if="status === statusMap.UPLOAD">
      <div class="success bg-full animate__animated animate__fadeInDown"></div>
      <div class="tips animate__animated animate__fadeInDown">报名成功</div>
      <div class="line bg-full animate__animated animate__fadeInLeft"></div>
      <div class="camera bg-full animate__animated animate__zoomIn">
        <input type="file" accept="image/*" @change="handleSelect" />
      </div>
      <div class="upload bg-full animate__animated animate__pulse animate__infinite">
        <input type="file" accept="image/*" @change="handleSelect" />
        <div class="hand bg-full"></div>
      </div>
    </div>
    <div class="preview" v-if="status === statusMap.PREVIEW">
      <div class="photo animate__animated animate__zoomIn">
        <div class="image">
          <img :src="photoUrl" alt="" width="100%" height="100%" />
        </div>
        <div class="text bg-full"></div>
      </div>
      <div class="save bg-full animate__animated animate__pulse animate__infinite"></div>
    </div>
    <div class="poster" v-if="posterUrl">
      <img :src="posterUrl" alt="" />
    </div>
  </div>
</template>

<script setup>
import Title from '@/components/Title.vue'
import { reactive, ref } from 'vue'
import { categoryList, companyList, groupList } from '@/constants.js'
import { base64ToFile, drawPoster, uploadFile } from '@/utils.js'
import { updatePersonalUrl, userApply } from '@/api/index.js'
import { toast } from 'vue3-toastify'
import { useGlobalStore } from '@/stores/global.js'
import { useRouter } from 'vue-router'

const globalStore = useGlobalStore()

const statusMap = {
  SUBMIT: 0,
  UPLOAD: 1,
  PREVIEW: 2
}

const getDefaultStatus = () => {
  if (globalStore.user?.id) {
    return statusMap.UPLOAD
  }
  return statusMap.SUBMIT
}

const status = ref(getDefaultStatus())

const router = useRouter()

const formData = reactive({
  company: '',
  name: '',
  number: '',
  group: '',
  category: '',
  works: ''
})

const validateFormData = () => {
  if (!formData.company) {
    return '请选择分公司'
  }
  if (!formData.name) {
    return '请输入姓名'
  }
  if (!formData.number) {
    return '请输入工号'
  }
  if (!formData.group) {
    return '请选择比武组别'
  }
  if (!formData.category) {
    return '请选择比武类别'
  }
  if (!formData.works) {
    return '请输入参赛作品名称'
  }
}

const handleSubmit = async () => {
  const errorMessage = validateFormData()
  if (errorMessage) {
    toast(errorMessage)
    return
  }
  if (
    !confirm('一旦提交无法修改，请您再次核对本人工号是否填写正确。\n（内勤输入P13，外勤输入工号）')
  ) {
    return
  }
  const loading = toast('加载中', { isLoading: true })
  try {
    const user = await userApply(formData)
    globalStore.setUser(user.data)
    if (!user.data.personalUrl) {
      status.value = statusMap.UPLOAD
    } else {
      router.push({ name: 'race' })
    }
  } finally {
    toast.remove(loading)
  }
}

const photoUrl = ref('')

const handleSelect = async (event) => {
  const [file] = event.target.files
  if (file.size > 10 * 1024 * 1024) {
    toast('上传图片大小不能超过10M')
    return
  }
  const reader = new FileReader()
  reader.readAsDataURL(file)
  reader.addEventListener('load', async (e) => {
    photoUrl.value = e.target.result
    status.value = statusMap.PREVIEW
    await handleUpload()
  })
}

const posterUrl = ref('')
const handleUpload = async () => {
  const poster = await drawPoster(photoUrl.value, globalStore.user)
  const type = 'image/jpeg'
  posterUrl.value = poster.toDataURL(type)
  const file = base64ToFile(posterUrl.value, 'poster.jpeg', type)
  const result = await uploadFile(file)
  await updatePersonalUrl(globalStore.user.id, result.url)
  globalStore.setUser({ personalUrl: result.url })
}
</script>

<style lang="less" scoped>
.form {
  margin-top: 80px;

  .form-item {
    display: flex;
    width: 1090px;
    height: 90px;
    background: #fadfaf;
    margin-bottom: 50px;
    padding: 0 30px;

    .label {
      line-height: 90px;
      padding: 0 30px;
      min-width: 225px;
    }

    .control {
      flex: 1;

      select,
      input {
        width: 100%;
        box-sizing: border-box;
        border: none;
        outline: none;
        height: 100%;
        background: none;
      }

      option {
        padding: 0;
      }
    }

    .icon {
      width: 90px;
      height: 90px;
      display: flex;
      align-items: center;
      justify-content: center;

      i {
        display: block;
      }
    }

    &:nth-child(1) {
      .icon {
        i {
          width: 76px;
          height: 75px;
          background-image: url(../assets/img/apply/company.png);
        }
      }
    }

    &:nth-child(2) {
      .icon {
        i {
          width: 61px;
          height: 64px;
          background-image: url(../assets/img/apply/name.png);
        }
      }
    }

    &:nth-child(3) {
      .icon {
        i {
          width: 68px;
          height: 57px;
          background-image: url(../assets/img/apply/number.png);
        }
      }
    }

    &:nth-child(4) {
      .icon {
        i {
          width: 81px;
          height: 64px;
          background-image: url(../assets/img/apply/group.png);
        }
      }
    }

    &:nth-child(5) {
      .icon {
        i {
          width: 63px;
          height: 63px;
          background-image: url(../assets/img/apply/category.png);
        }
      }
    }

    &:nth-child(6) {
      .icon {
        i {
          width: 57px;
          height: 52px;
          background-image: url(../assets/img/apply/works.png);
        }
      }
    }
  }

  .submit {
    width: 1090px;
    height: 90px;
    background-image: url(../assets/img/apply/submit.png);
  }
}

.result {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;

  .tips {
    margin-top: 60px;
    font-size: 90px;
    color: #1361a2;
  }

  .success {
    width: 272px;
    height: 249px;
    background-image: url(../assets/img/apply/success.png);
  }

  .line {
    margin-top: 180px;
    width: 745px;
    height: 41px;
    background-image: url(../assets/img/apply/line.png);
  }

  .camera {
    margin-top: 180px;
    width: 315px;
    height: 314px;
    background-image: url(../assets/img/apply/camera.png);
  }

  .upload {
    margin-top: 70px;
    width: 787px;
    height: 137px;
    background-image: url(../assets/img/apply/upload.png);
  }
}

.preview {
  margin-top: 90px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;

  .photo {
    width: 712px;
    height: 712px;
    position: relative;

    .image {
      width: 100%;
      height: 100%;
      border-radius: 50%;
      overflow: hidden;

      img {
        width: 100%;
        height: 100%;
      }
    }
  }

  .text {
    position: absolute;
    width: 730px;
    height: 662px;
    right: -230px;
    bottom: -260px;
    background-image: url(../assets/img/apply/text.png);
  }

  .save {
    margin-top: 240px;
    width: 514px;
    height: 125px;
    background-image: url(../assets/img/apply/save.png);
  }
}

.poster {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 9;
  width: 100%;
  height: 100%;
  opacity: 0;

  img {
    width: 100%;
    height: 100%;
  }
}

.upload,
.camera {
  position: relative;

  input {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
  }
}
</style>
